#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>

#ifdef __linux__
GtkWidget* gtk_dialog_get_content_area(GtkDialog* dialog) {
        return dialog->vbox;
}
#endif

enum {
	COLUMN_CODIGO = 0,
	COLUMN_NOME,
	COLUMN_PRECO,
	COLUMN_QUANTIDADE,
	N_COLUMNS
};

enum {
	RESPONSE_SALVAR = 0,
	RESPONSE_CANCELAR
};

GtkWidget* window;
GtkWidget* scrolled_window;

GtkWidget* vbox;
GtkWidget* table1;
GtkWidget* table2;
GtkWidget* table3;

GtkWidget* menuBar;
GtkWidget* menuArquivo;
GtkWidget* menuItemArquivo;
GtkWidget* menuItemAbrir;
GtkWidget* menuItemSalvar;
GtkWidget* menuItemSair;

GtkWidget* lblCodigo;
GtkWidget* txtCodigo;

GtkWidget* lblNome;
GtkWidget* txtNome;

GtkWidget* lblPreco;
GtkWidget* txtPreco;

GtkWidget* lblQuantidade;
GtkWidget* txtQuantidade;

GtkWidget* btnAdicionarProduto;

GtkWidget* treeView;
GtkTreeViewColumn* columnCodigo;
GtkTreeViewColumn* columnNome;
GtkTreeViewColumn* columnPreco;
GtkTreeViewColumn* columnQuantidade;
GtkCellRenderer *renderer;
GtkTreeSelection* selection;
GtkTreeSortable* sortable;
GtkListStore* store;

GtkWidget* btnEditarProduto;
GtkWidget* btnRemoverProduto;

GtkWidget* fileDialog;
GtkWidget* editDialog;
GtkWidget* errDialog;

typedef struct _No {
	int codigo;
	char nome[200];
	float preco;
	int quantidade;

	struct _No* prox;
} No;

gboolean foreach_func(GtkTreeModel* model, GtkTreePath* path, GtkTreeIter *iter, GList** rowref_list) {
	int codigo;

	gtk_tree_model_get(model, iter, COLUMN_CODIGO, &codigo, -1);

	GtkTreeRowReference* rowref = gtk_tree_row_reference_new(model, path);
	*rowref_list = g_list_append(*rowref_list, rowref);

	return FALSE;
}

void abrirCallback(GtkWidget* widget, No* cab) {
	fileDialog = gtk_file_chooser_dialog_new("Abrir", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
	int response = gtk_dialog_run(GTK_DIALOG(fileDialog));
	if (response == GTK_RESPONSE_ACCEPT) {
		char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fileDialog));
		
		FILE* fp;
		fp = fopen(filename, "r"); /* FIXME: acentos no caminho do arquivo a ser aberto */

		if (fp != NULL) {
			GtkListStore* store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(treeView)));

			GList* rr_list = NULL;

			gtk_tree_model_foreach(GTK_TREE_MODEL(store), (GtkTreeModelForeachFunc)foreach_func, &rr_list);

			for (GList* node = rr_list; node != NULL; node = node -> next) {
				GtkTreePath *path;

				path = gtk_tree_row_reference_get_path((GtkTreeRowReference*)node->data);

				if (path) {
					GtkTreeIter iter;
					
					if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path)) {
						gtk_list_store_remove(store, &iter);
					}
				}
			}

			g_list_foreach(rr_list, (GFunc)gtk_tree_row_reference_free, NULL);
			g_list_free(rr_list);

			No* atual = cab->prox;
			while (atual != NULL) {
				No* temp = atual->prox;

				free(atual);

				atual = temp;
			}

			cab->prox = NULL;

			int codigo;
			char nome[200];
			float preco;
			int quantidade;

			while (fscanf(fp, "%d %f %d %[^\n]", &codigo, &preco, &quantidade, nome) != EOF) {
				No* atual = cab;
				while (atual->prox != NULL) {
					if (atual->prox->codigo > codigo) break;

					atual = atual->prox;
				}

				No* temp = atual->prox;
				atual->prox = (No*)malloc(sizeof(No));

				atual->prox->codigo = codigo;
				strcpy(atual->prox->nome, nome);
				atual->prox->preco = preco;
				atual->prox->quantidade = quantidade;
				atual->prox->prox = temp;

				GtkTreeIter iter;
				gtk_list_store_append(store, &iter);
				gtk_list_store_set(store, &iter, COLUMN_CODIGO, codigo, COLUMN_NOME, nome, COLUMN_PRECO, preco, COLUMN_QUANTIDADE, quantidade, -1);
			}

			fclose(fp);
		}
		else {
			perror("Erro");

			errDialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Erro ao abrir arquivo.");
			gtk_window_set_title(GTK_WINDOW(errDialog), "Erro");
			gtk_dialog_run(GTK_DIALOG(errDialog));
			gtk_widget_destroy(errDialog);
		}

		g_free(filename);
	}

	gtk_widget_destroy(fileDialog);
}

void salvarCallback(GtkWidget* widget, No* cab) {
	fileDialog = gtk_file_chooser_dialog_new("Salvar", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
	gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(fileDialog), TRUE);
	gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(fileDialog), "Untitled document.products");
	int response = gtk_dialog_run(GTK_DIALOG(fileDialog));

	if (response == GTK_RESPONSE_ACCEPT) {
		char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fileDialog));
		puts(filename);

		FILE* fp;
		fp = fopen(filename, "w"); /* FIXME: acentos no caminho do arquivo a ser salvo */

		if (fp != NULL) {
			No* atual = cab;
			while (atual->prox != NULL) {
				fprintf(fp, "%d %f %d %s\n", atual->prox->codigo, atual->prox->preco, atual->prox->quantidade, atual->prox->nome);

				atual = atual->prox;
			}

			fclose(fp);

		}
		else {
			perror("Erro");

			errDialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Erro ao salvar arquivo.");
			gtk_window_set_title(GTK_WINDOW(errDialog), "Erro");
			gtk_dialog_run(GTK_DIALOG(errDialog));
			gtk_widget_destroy(errDialog);
		}

		g_free(filename);
	}

	gtk_widget_destroy(fileDialog);
}

GdkPixbuf* create_pixbuf(char* filename) {
	GdkPixbuf* pixbuf;
	GError* error = NULL;

	pixbuf = gdk_pixbuf_new_from_file(filename, &error);
	if (!pixbuf) {
		fprintf(stderr, "%s\n", error->message);
		g_error_free(error);
	}

	return pixbuf;
}

void clickedBtnAdicionarProduto(GtkWidget* button, No* cab) {
	No* cab2 = cab;
	while (cab2->prox != NULL) {
		cab2 = cab2->prox;
	}
	char* strCodigo = (char*)gtk_entry_get_text(GTK_ENTRY(txtCodigo));
	char* nome = (char*)gtk_entry_get_text(GTK_ENTRY(txtNome));
	char* strPreco = (char*)gtk_entry_get_text(GTK_ENTRY(txtPreco));
	char* strQuantidade = (char*)gtk_entry_get_text(GTK_ENTRY(txtQuantidade));

	if (!strlen(strCodigo) || !strlen(nome) || !strlen(strPreco) || !strlen(strQuantidade)) {
		errDialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Preencha todos os campos.");
		gtk_window_set_title(GTK_WINDOW(errDialog), "Erro");
		gtk_dialog_run(GTK_DIALOG(errDialog));
		gtk_widget_destroy(errDialog);

		return;
	}

	bool erro = false;

	for (int i = 0; i < strlen(strCodigo); i++) {
		if (!isdigit(strCodigo[i])) {
			erro = true;
		}
	}

	for (int i = 0, pontos = 0, virgulas = 0; i < strlen(strPreco); i++) {
		if (!isdigit(strPreco[i])) {
			if (strPreco[i] == '.') {
				strPreco[i] = ',';

				pontos++;
			}
			else if (strPreco[i] == ',') {
				virgulas++;
			}
			else {
				erro = true;
			}

			if (virgulas + pontos > 1) {
				erro = true;
			}
		}
	}

	for (int i = 0; i < strlen(strQuantidade); i++) {
		if (!isdigit(strQuantidade[i])) {
			erro = true;
		}
	}

	if (erro) {
		errDialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Forneça dados válidos.");
		gtk_window_set_title(GTK_WINDOW(errDialog), "Erro");
		gtk_dialog_run(GTK_DIALOG(errDialog));
		gtk_widget_destroy(errDialog);

		return;
	}

	int codigo = atoi(strCodigo);
	float preco = atof(strPreco);
	int quantidade = atoi(strQuantidade);

	while (cab->prox != NULL) {
		if (cab->prox->codigo > codigo) {
			break;
		}
		if (cab->prox->codigo == codigo) {
			errDialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "O código fornecido já está sendo utilizado.");
			gtk_window_set_title(GTK_WINDOW(errDialog), "Erro");
			gtk_dialog_run(GTK_DIALOG(errDialog));
			gtk_widget_destroy(errDialog);

			return;
		}
		cab = cab->prox;
	}

	No* temp = cab->prox;
	cab->prox = (No*)malloc(sizeof(No));
	cab->prox->prox = temp;

	cab->prox->codigo = codigo;
	strcpy(cab->prox->nome, nome);
	cab->prox->preco = preco;
	cab->prox->quantidade = quantidade;

	GtkListStore* store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(treeView)));
	GtkTreeIter iter;

	gtk_list_store_append(store, &iter);
	gtk_list_store_set(store, &iter, COLUMN_CODIGO, codigo, COLUMN_NOME, nome, COLUMN_PRECO, preco, COLUMN_QUANTIDADE, quantidade, -1);

	gtk_entry_set_text(GTK_ENTRY(txtCodigo), "");
	gtk_entry_set_text(GTK_ENTRY(txtNome), "");
	gtk_entry_set_text(GTK_ENTRY(txtPreco), "");
	gtk_entry_set_text(GTK_ENTRY(txtQuantidade), "");
}

void clickedBtnEditarProduto(GtkWidget* button, No* cab) {
	GtkListStore* store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(treeView)));
	GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeView));
	GtkTreeIter iter;

	if (gtk_tree_selection_get_selected(GTK_TREE_SELECTION(selection), &model, &iter)) {
		editDialog = gtk_dialog_new_with_buttons("Editando Produtos", GTK_WINDOW(window), (GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR), "Salvar", RESPONSE_SALVAR, "Cancelar", RESPONSE_CANCELAR, NULL);
		gtk_window_set_resizable(GTK_WINDOW(editDialog), FALSE);

		GtkWidget* contentArea = gtk_dialog_get_content_area(GTK_DIALOG(editDialog));
		GtkWidget* editDialogTable = gtk_table_new(3, 2, TRUE);

		GtkWidget* editDialogLblNome = gtk_label_new("Nome:");
		GtkWidget* editDialogTxtNome = gtk_entry_new();

		GtkWidget* editDialogLblPreco = gtk_label_new("Preço:");
		GtkWidget* editDialogTxtPreco = gtk_entry_new();

		GtkWidget* editDialogLblQuantidade = gtk_label_new("Quantidade:");
		GtkWidget* editDialogTxtQuantidade = gtk_entry_new();

		gtk_table_attach_defaults(GTK_TABLE(editDialogTable), editDialogLblNome, 0, 1, 0, 1);
		gtk_table_attach_defaults(GTK_TABLE(editDialogTable), editDialogTxtNome, 1, 2, 0, 1);

		gtk_table_attach_defaults(GTK_TABLE(editDialogTable), editDialogLblPreco, 0, 1, 1, 2);
		gtk_table_attach_defaults(GTK_TABLE(editDialogTable), editDialogTxtPreco, 1, 2, 1, 2);

		gtk_table_attach_defaults(GTK_TABLE(editDialogTable), editDialogLblQuantidade, 0, 1, 2, 3);
		gtk_table_attach_defaults(GTK_TABLE(editDialogTable), editDialogTxtQuantidade, 1, 2, 2, 3);

		gtk_container_add(GTK_CONTAINER(contentArea), editDialogTable);

		char* nome;
		float preco;
		int quantidade;

		gtk_tree_model_get(model, &iter, COLUMN_NOME, &nome, COLUMN_PRECO, &preco, COLUMN_QUANTIDADE, &quantidade, -1);

		char strPreco[200];
		char strQuantidade[200];

		sprintf(strPreco, "%.2f", preco);
		sprintf(strQuantidade, "%d", quantidade);

		gtk_entry_set_text(GTK_ENTRY(editDialogTxtNome), nome);
		gtk_entry_set_text(GTK_ENTRY(editDialogTxtPreco), strPreco);
		gtk_entry_set_text(GTK_ENTRY(editDialogTxtQuantidade), strQuantidade);

		gtk_widget_show_all(contentArea);

		while (1) {
			int result = gtk_dialog_run(GTK_DIALOG(editDialog));
			
			if (result == RESPONSE_SALVAR) {

				int codigo;
				gtk_tree_model_get(model, &iter, COLUMN_CODIGO, &codigo, -1);

				char* editDialogNome = (char*)gtk_entry_get_text(GTK_ENTRY(editDialogTxtNome));
				char* strEditDialogPreco = (char*)gtk_entry_get_text(GTK_ENTRY(editDialogTxtPreco));
				char* strEditDialogQuantidade = (char*)gtk_entry_get_text(GTK_ENTRY(editDialogTxtQuantidade));

				if (!strlen(editDialogNome) || !strlen(strEditDialogPreco) || !strlen(strEditDialogQuantidade)) {
					errDialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Preencha todos os campos.");
					gtk_window_set_title(GTK_WINDOW(errDialog), "Erro");
					gtk_dialog_run(GTK_DIALOG(errDialog));
					gtk_widget_destroy(errDialog);

					continue;
				}

				bool erro = false;

				for (int i = 0, pontos = 0, virgulas = 0; i < strlen(strEditDialogPreco); i++) {
					if (!isdigit(strEditDialogPreco[i])) {
						if (strEditDialogPreco[i] == '.') {
							strEditDialogPreco[i] = ',';
							pontos++;
						}

						else if (strEditDialogPreco[i] == ',') {
							virgulas++;
						}
						else {
							erro = true;
						}

						if (virgulas + pontos > 1) {
							erro = true;
						}
					}
				}

				for (int i = 0; i < strlen(strEditDialogQuantidade); i++) {
					if (!isdigit(strEditDialogQuantidade[i])) {
						erro = true;
					}
				}

				if (erro) {
					errDialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Forneca dados validos.");
					gtk_window_set_title(GTK_WINDOW(errDialog), "Erro");
					gtk_dialog_run(GTK_DIALOG(errDialog));
					gtk_widget_destroy(errDialog);

					continue;
				}

				float editDialogPreco = atof(strEditDialogPreco);
				int editDialogQuantidade = atoi(strEditDialogQuantidade);
				No* atual = cab;
				while (atual->prox->codigo != codigo) {
					atual = atual->prox;
				}

				strcpy(atual->prox->nome, editDialogNome);
				atual->prox->preco = editDialogPreco;
				atual->prox->quantidade = editDialogQuantidade;

				gtk_list_store_set(store, &iter, COLUMN_CODIGO, codigo, COLUMN_NOME, editDialogNome, COLUMN_PRECO, editDialogPreco, COLUMN_QUANTIDADE, editDialogQuantidade, -1);
			}

			gtk_widget_destroy(editDialog);

			return;
		}
	
	}
	else {
		errDialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Selecione um produto.");
		gtk_window_set_title(GTK_WINDOW(errDialog), "Erro");
		gtk_dialog_run(GTK_DIALOG(errDialog));
		gtk_widget_destroy(errDialog);

		return;
	}
}

void clickedBtnRemoverProduto(GtkWidget* button, No* cab) {
	GtkListStore* store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(treeView)));
	GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeView));
	GtkTreeIter iter;

	if (gtk_tree_selection_get_selected(GTK_TREE_SELECTION(selection), &model, &iter)) {
		int codigo;

		gtk_tree_model_get(model, &iter, COLUMN_CODIGO, &codigo, -1);

		while (cab->prox != NULL) {
			if (cab->prox->codigo == codigo) {
				No* temp = cab->prox->prox;

				free(cab->prox);
				cab->prox = temp;

				gtk_list_store_remove(store, &iter);

				return;
			}
			cab = cab->prox;
		}
	}
	else {
		errDialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Selecione um produto.");
		gtk_window_set_title(GTK_WINDOW(errDialog), "Erro");
		gtk_dialog_run(GTK_DIALOG(errDialog));
		gtk_widget_destroy(errDialog);

		return;
	}
}

void cellPrecoFunc(GtkTreeViewColumn* col, GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter, gpointer data) {
	float preco;
	char strPreco[200];

	gtk_tree_model_get(model, iter, COLUMN_PRECO, &preco, -1);

	sprintf(strPreco, "%.2f", preco);

	g_object_set(renderer, "text", strPreco, NULL);
}

void quit(GtkWidget* window, No* cab) {
	while (cab != NULL) {
		No* temp = cab->prox;

		free(cab);

		cab = temp;
	}

	gtk_main_quit();
}

int sort_func_codigo(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer data) {
	int codigo1;
	int codigo2;

	gtk_tree_model_get(model, a, COLUMN_CODIGO, &codigo1, -1);
	gtk_tree_model_get(model, b, COLUMN_CODIGO, &codigo2,  -1);


	return codigo1 - codigo2;
}

int sort_func_nome(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer data) {
	char* nome1;
	char* nome2;

	gtk_tree_model_get(model, a, COLUMN_NOME, &nome1, -1);
	gtk_tree_model_get(model, b, COLUMN_NOME, &nome2,  -1);

	return strcmp(nome1, nome2);
}

int sort_func_preco(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer data) {
	int preco1;
	int preco2;

	gtk_tree_model_get(model, a, COLUMN_PRECO, &preco1, -1);
	gtk_tree_model_get(model, b, COLUMN_PRECO, &preco2,  -1);

	return (int)(preco1 - preco2);
}

int sort_func_quantidade(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer data) {
	int quantidade1;
	int quantidade2;

	gtk_tree_model_get(model, a, COLUMN_QUANTIDADE, &quantidade1, -1);
	gtk_tree_model_get(model, b, COLUMN_QUANTIDADE, &quantidade2,  -1);


	return quantidade1 - quantidade2;
}


int main(int argc, char** argv) {
	No* cab = (No*)malloc(sizeof(No));
	cab->prox = NULL;

	gtk_init(&argc, &argv);

	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_window_set_default_size(GTK_WINDOW(window), 640, 480);
	gtk_window_set_title(GTK_WINDOW(window), "Produtos");
	gtk_window_set_icon(GTK_WINDOW(window), create_pixbuf("icon.png"));

	g_signal_connect(window, "destroy", G_CALLBACK(quit), cab);

	scrolled_window = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);

	vbox = gtk_vbox_new(FALSE, 1);
	
	table1 = gtk_table_new(5, 2, TRUE);
	table2 = gtk_table_new(1, 1, TRUE);
	table3 = gtk_table_new(1, 2, TRUE);

	menuBar = gtk_menu_bar_new();

	menuItemArquivo = gtk_menu_item_new_with_label("Arquivo");
	menuArquivo = gtk_menu_new();
	menuItemAbrir = gtk_image_menu_item_new_from_stock(GTK_STOCK_OPEN, NULL);
	g_signal_connect(menuItemAbrir, "activate", G_CALLBACK(abrirCallback), cab);

	menuItemSalvar = gtk_image_menu_item_new_from_stock(GTK_STOCK_SAVE, NULL);
	g_signal_connect(menuItemSalvar, "activate", G_CALLBACK(salvarCallback), cab);

	menuItemSair = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL);
	g_signal_connect(menuItemSair, "activate", G_CALLBACK(quit), NULL);

	gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuItemArquivo), menuArquivo);

	gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), menuItemArquivo);
	gtk_menu_shell_append(GTK_MENU_SHELL(menuArquivo), menuItemAbrir);
	gtk_menu_shell_append(GTK_MENU_SHELL(menuArquivo), menuItemSalvar);
	gtk_menu_shell_append(GTK_MENU_SHELL(menuArquivo), menuItemSair);

	lblCodigo = gtk_label_new("Código:");
	txtCodigo = gtk_entry_new();

	lblNome = gtk_label_new("Nome:");
	txtNome = gtk_entry_new();

	lblPreco = gtk_label_new("Preço:");
	txtPreco = gtk_entry_new();

	lblQuantidade = gtk_label_new("Quantidade:");
	txtQuantidade = gtk_entry_new();

	btnAdicionarProduto = gtk_button_new_with_label("Adicionar Produto");
	gtk_widget_set_size_request(btnAdicionarProduto, 200, 20);
	g_signal_connect(btnAdicionarProduto, "clicked", G_CALLBACK(clickedBtnAdicionarProduto), cab);

	treeView = gtk_tree_view_new();
	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeView));

	renderer = gtk_cell_renderer_text_new();

	columnCodigo = gtk_tree_view_column_new_with_attributes("Código", renderer, "text", COLUMN_CODIGO, NULL);
	columnNome = gtk_tree_view_column_new_with_attributes("Nome", renderer, "text", COLUMN_NOME, NULL);
	columnPreco = gtk_tree_view_column_new_with_attributes("Preço", renderer, "text", COLUMN_PRECO, NULL);
	columnQuantidade = gtk_tree_view_column_new_with_attributes("Quantidade", renderer, "text", COLUMN_QUANTIDADE, NULL);

	gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), columnCodigo);
	gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), columnNome);
	gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), columnPreco);
	gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), columnQuantidade);

	gtk_tree_view_column_set_cell_data_func(columnPreco, renderer, cellPrecoFunc, NULL, NULL);

	store = gtk_list_store_new(N_COLUMNS, G_TYPE_INT, G_TYPE_STRING, G_TYPE_FLOAT, G_TYPE_INT);
	gtk_tree_view_set_model(GTK_TREE_VIEW(treeView), GTK_TREE_MODEL(store));

	sortable = GTK_TREE_SORTABLE(store);

	gtk_tree_sortable_set_sort_func(sortable, COLUMN_CODIGO, sort_func_codigo, NULL, NULL);
	gtk_tree_sortable_set_sort_func(sortable, COLUMN_NOME, sort_func_nome, NULL, NULL);
	gtk_tree_sortable_set_sort_func(sortable, COLUMN_PRECO, sort_func_preco, NULL, NULL);
	gtk_tree_sortable_set_sort_func(sortable, COLUMN_QUANTIDADE, sort_func_quantidade, NULL, NULL);

	gtk_tree_view_column_set_sort_column_id(columnCodigo, COLUMN_CODIGO);
	gtk_tree_view_column_set_sort_column_id(columnNome, COLUMN_NOME);
	gtk_tree_view_column_set_sort_column_id(columnPreco, COLUMN_PRECO);
	gtk_tree_view_column_set_sort_column_id(columnQuantidade, COLUMN_QUANTIDADE);

	g_object_unref(store);

	btnEditarProduto = gtk_button_new_with_label("Editar Produto");
	g_signal_connect(btnEditarProduto, "clicked", G_CALLBACK(clickedBtnEditarProduto), cab);

	btnRemoverProduto = gtk_button_new_with_label("Remover Produto");
	g_signal_connect(btnRemoverProduto, "clicked", G_CALLBACK(clickedBtnRemoverProduto), cab);

	gtk_table_attach_defaults(GTK_TABLE(table1), menuBar, 0, 2, 0, 1);
	gtk_table_attach_defaults(GTK_TABLE(table1), lblCodigo, 0, 1, 1, 2);
	gtk_table_attach_defaults(GTK_TABLE(table1), txtCodigo, 1, 2, 1, 2);

	gtk_table_attach_defaults(GTK_TABLE(table1), lblNome, 0, 1, 2, 3);
	gtk_table_attach_defaults(GTK_TABLE(table1), txtNome, 1, 2, 2, 3);

	gtk_table_attach_defaults(GTK_TABLE(table1), lblPreco, 0, 1, 3, 4);
	gtk_table_attach_defaults(GTK_TABLE(table1), txtPreco, 1, 2, 3, 4);

	gtk_table_attach_defaults(GTK_TABLE(table1), lblQuantidade, 0, 1, 4, 5);
	gtk_table_attach_defaults(GTK_TABLE(table1), txtQuantidade, 1, 2, 4, 5);

	gtk_table_attach_defaults(GTK_TABLE(table1), btnAdicionarProduto, 0, 2, 5, 6);

	gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), treeView);
	gtk_table_attach_defaults(GTK_TABLE(table2), scrolled_window, 0, 1, 0, 1);

	gtk_table_attach_defaults(GTK_TABLE(table3), btnEditarProduto, 0, 1, 0, 1);
	gtk_table_attach_defaults(GTK_TABLE(table3), btnRemoverProduto, 1, 2, 0, 1);

	gtk_box_pack_start(GTK_BOX(vbox), table1, FALSE, FALSE, 0);
	gtk_box_pack_start(GTK_BOX(vbox), table2, TRUE, TRUE, 0);
	gtk_box_pack_start(GTK_BOX(vbox), table3, FALSE, FALSE, 0);
	
	gtk_container_add(GTK_CONTAINER(window), vbox);

	gtk_widget_show_all(window);

	gtk_main();
	return 0;
}
